package de.idgard.android.utils;

public final class Base64Encoder {

	private static final char[] base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
			.toCharArray();

	private static final int splitLinesAt = 76;

	private static byte[] zeroPad(int length, byte[] bytes) {
		byte[] padded = new byte[length];
		System.arraycopy(bytes, 0, padded, 0, bytes.length);
		return padded;
	}

	public static String encode(byte[] bytes) {
		String encoded = "";
		byte[] stringArray = bytes;
		int paddingCount = (3 - (stringArray.length % 3)) % 3;

		stringArray = zeroPad(stringArray.length + paddingCount, stringArray);

		for (int i = 0; i < stringArray.length; i += 3) {
			int j = ((stringArray[i] & 0xff) << 16)
					+ ((stringArray[i + 1] & 0xff) << 8)
					+ (stringArray[i + 2] & 0xff);
			encoded = encoded + base64code[((j >> 18) & 0x3f)]
					+ base64code[((j >> 12) & 0x3f)]
					+ base64code[((j >> 6) & 0x3f)] + base64code[(j & 0x3f)];
		}

		return splitLines(encoded.substring(0, encoded.length() - paddingCount)
				+ "==".substring(0, paddingCount));

	}
	
	
    public static byte[] decode(String s) {
    	
      int end = 0;	// end state
      if (s.endsWith("=")) {
	  end++;
      }
      if (s.endsWith("==")) {
	  end++;
      }
      int len = (s.length() + 3)/4 * 3 - end;
      byte[] result = new byte[len];
      int dst = 0;
      try {
	  for(int src = 0; src< s.length(); src++) {
	      int code =  new String(base64code).indexOf(s.charAt(src));
	      if (code == -1) {
	          break;
	      }
	      switch (src%4) {
	      case 0:
	          result[dst] = (byte) (code<<2);
	          break;
	      case 1: 
	          result[dst++] |= (byte) ((code>>4) & 0x3);
	          result[dst] = (byte) (code<<4);
	          break;
	      case 2:
	          result[dst++] |= (byte) ((code>>2) & 0xf);
	          result[dst] = (byte) (code<<6);
	          break;
	      case 3:
	          result[dst++] |= (byte) (code & 0x3f);
	          break;
	      }
	  }
      } catch (ArrayIndexOutOfBoundsException e) {}
      return result;
    }

	public static String encode(String string) {
		byte[] stringArray;
		try {
			stringArray = string.getBytes("UTF8");
		} catch (Exception ignored) {
			stringArray = string.getBytes();
		}
		return encode(stringArray);

	}

	private static String splitLines(String string) {

		String lines = "";
		for (int i = 0; i < string.length(); i += splitLinesAt) {
			lines += string.substring(i,
					Math.min(string.length(), i + splitLinesAt));
		}
		return lines;
	}
}
